const mysql = require('mysql');
const MysqlConnection = require('./mysql_connection');

class MysqlClient{
    constructor(host,port,user,password,database,cfg=null){
        this.connection = null;
        this.connectInfo = null;
        if (cfg) {
            this.connectInfo = cfg;
        } else {
            this.connectInfo = {
                dateStrings: false,
                multipleStatements:false,
                supportBigNumbers: false,
                bigNumberStrings: false
            }
        }
        this.connectInfo.host = host;
        this.connectInfo.port = port;
        this.connectInfo.user = user;
        this.connectInfo.password = password;
        this.connectInfo.database = database;
    }
    printError(err) {
        if (global.log) {
            global.log.error(err);
        } else {
            console.error(err);
        }
    }
    //建立连接
    _connect(){
        let self = this;
        return new Promise(function (resolve, reject) {
            const connection = mysql.createConnection(self.connectInfo);
            connection.on("error", (err)=>{
                self.printError(err);
            });
            connection.on("end", (err)=>{
                self.connection = null;
            });
            connection.connect((err)=>{
                if (err) {
                    reject("mysql connect falied!"+err.message);
                } else {
                    self.connection = new MysqlConnection(connection);
                    resolve("mysql connect succeeded!");
                }
            });
        })
    }
    //关闭连接
    close(){
        if (this.connection) {
            this.connection.close();
            this.connection = null;
        }
    }
    //获取查询结果
    async query(sql, param=null){
        if (!this.connection) {
            await this._connect();
        }
        return await this.connection.query(sql, param);
    }
    //执行查询不反回结果
    async execute(sql, param=null){
        try {
            if (!this.connection) {
                await this._connect();
            }
            await this.connection.execute(sql, param);
        } catch (error) {
            this.printError(error);
        }
        return null;
    }
    //查询一次
    async queryOnce(sql, param=null){
        const ret = await this.query(sql, param);
        this.close();
        return ret;
    }
    //查询一次不反回结果
    async executeOnce(sql, param=null){
        await this.execute(sql, param);
        this.close();
        return null;
    }
    //执行一次事务,回调函数返回true则提交，返回false则回滚
    async transaction(callback){
        let err = null;
        let ret = false;
        try {
            if (!this.connection) {
                await this._connect();
            }
            await this.connection.beginTransaction();
            ret = await callback(this.connection);
            if (ret) {
                await this.connection.commit();
            } else {
                await this.connection.rollback();
            }
        } catch (error) {
            err = error;
            if (this.connection) {
                await this.connection.rollback();
            }
        }
        if (err) {
            throw err;
        }
        return ret;
    }
    //按一次事务查询一组语句,有错误则回滚
    async executeList(sqlArr, paramArr){
        let err = null;
        try {
            if (!this.connection) {
                await this._connect();
            }
            let tmp = await this.connection.beginTransaction();
            for (let i = 0; i < sqlArr.length; i++) {
                tmp = await this.connection.query(sqlArr[i], paramArr[i]);
            }
            await this.connection.commit();
        } catch (error) {
            err = error;
            if (this.connection) {
                await this.connection.rollback();
            }
        }
        if (err) {
            throw err;
        }
        return null;
    }
}

module.exports = MysqlClient;
